/*******************************************************************************
 * Copyright (c) 2010 European Software Institute - Tecnalia.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Author - Adri�n Noguero (adrian.noguero@esi.es)
 *     
 *******************************************************************************/

package es.esi.gemde.modelvalidator.service.impl;

import java.util.List;
import java.util.Vector;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;

import es.esi.gemde.modelvalidator.ModelValidatorPlugin;
import es.esi.gemde.modelvalidator.service.IValidationResult;
import es.esi.gemde.modelvalidator.service.IValidationTarget;


/**
 * The implementation of the {@link IValidationResult} interface.
 *
 * @author Adri�n Noguero (adrian.noguero@esi.es)
 * @version 1.0
 * @since 1.0
 *
 */
public class ValidationResult implements IValidationResult {

	private int status;
	private List<IValidationTarget> successfulConstraints;
	private List<IValidationTarget> failedConstraints;
	private List<String> messages;
	
	
	/**
	 * Default constructor. Creates an empty and successful ValidationResult instance.
	 *
	 */
	public ValidationResult() {
		status = IStatus.OK;
		successfulConstraints = new Vector<IValidationTarget>();
		failedConstraints = new Vector<IValidationTarget>();
		messages = new Vector<String>();
	}
	
	/**
	 * Specific constructor. Explicitly initializes the created ValidationResult instance.
	 *
	 *@param status the status of this element as defined in {@link IStatus}.
	 *@param successfulConstraints the list of pairs constraint/target that were successfully parsed, can be null.
	 *@param failedConstraints the list of pairs constraint/target that reported a problem when parsed, can be null.
	 *@throws IllegalArgumentException if a illegal status value was provided.
	 */
	public ValidationResult(int status, List<IValidationTarget> successfulConstraints, List<IValidationTarget> failedConstraints) throws IllegalArgumentException{
		if (status != IStatus.OK && status != IStatus.ERROR && status != IStatus.INFO && status != IStatus.WARNING) {
			throw new IllegalArgumentException("Illegal status value was provided");
		}
		
		this.status = status;
		if (successfulConstraints == null) {
			this.successfulConstraints = new Vector<IValidationTarget>();
		}
		else {
			this.successfulConstraints = successfulConstraints;
		}
		
		if (failedConstraints == null) {
			this.failedConstraints = new Vector<IValidationTarget>();
		}
		else {
			this.failedConstraints = successfulConstraints;
		}
	}
	
	/* (non-Javadoc)
	 * @see es.esi.gemde.modelvalidator.service.IValidationResult#getFailedConstraints()
	 */
	@Override
	public List<IValidationTarget> getFailedConstraints() {
		return failedConstraints;
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.modelvalidator.service.IValidationResult#getStatusCode()
	 */
	@Override
	public int getStatusCode() {
		return status;
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.modelvalidator.service.IValidationResult#getSuccessfulConstraints()
	 */
	@Override
	public List<IValidationTarget> getSuccessfulConstraints() {
		return successfulConstraints;
	}

	/* (non-Javadoc)
	 * @see es.esi.gemde.modelvalidator.service.IValidationResult#getMessages()
	 */
	@Override
	public String[] getMessages() {
		return messages.toArray(new String[0]);
	}
	
	/**
	 * This method adds a new message to the list. It is not intended to be used outside the Model Validation plug-in.
	 * 
	 * @param message the text message to be included.
	 */
	public void addMessage (String message) {
		messages.add(message);
	}
	
	
	/**
	 * A method used to change the status of this ValidationResult instance. It is not intended to be used outside this plug-in.
	 * 
	 * @param status the new status value as defined in {@link IStatus}.
	 * @throws IllegalArgumentException if an illegal status value is provided.
	 */
	public void setStatus (int status) throws IllegalArgumentException {
		if (status != IStatus.OK && status != IStatus.ERROR && status != IStatus.INFO && status != IStatus.WARNING) {
			throw new IllegalArgumentException("Illegal status value was provided");
		}
		this.status = status;
	}

	@Override
	public MultiStatus asMultiStatus() {
		String summary = "Validation results:\n\t* Successful constraints: " + successfulConstraints.size() + "\n\t* Failed constraints: " + failedConstraints.size();
		MultiStatus result = new MultiStatus(ModelValidatorPlugin.PLUGIN_ID, status, summary, null);
		for (IValidationTarget fail : failedConstraints) {
			String severityTag = null;
			if (fail.getConstraint().getSeverity() == IStatus.ERROR) {
				severityTag = "ERROR: ";
			}
			else if (fail.getConstraint().getSeverity() == IStatus.WARNING) {
				severityTag = "WARNING: ";
			}
			else {
				severityTag = "INFO: ";
			}
			result.add(new Status(fail.getConstraint().getSeverity(), ModelValidatorPlugin.PLUGIN_ID, severityTag + "Constraint " + fail.getConstraint().getCategory() + "::" + fail.getConstraint().getName() + " failed on target: " + fail.getTarget().toString()));
		}
		return result;
	}

}
